package org.diffshop.ware.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.diffshop.common.constant.WareConstant;
import org.diffshop.common.utils.PageUtils;
import org.diffshop.common.utils.Query;
import org.diffshop.ware.dao.WmsPurchaseDao;
import org.diffshop.ware.entity.WmsPurchaseDetailEntity;
import org.diffshop.ware.entity.WmsPurchaseEntity;
import org.diffshop.ware.service.WmsPurchaseDetailService;
import org.diffshop.ware.service.WmsPurchaseService;
import org.diffshop.ware.service.WmsWareSkuService;
import org.diffshop.ware.vo.MergePurchaseDetailVO;
import org.diffshop.ware.vo.PurchaseDoneVO;
import org.diffshop.ware.vo.PurchaseItemDoneVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("wmsPurchaseService")
public class WmsPurchaseServiceImpl extends ServiceImpl<WmsPurchaseDao, WmsPurchaseEntity> implements WmsPurchaseService {
    @Autowired
    private WmsPurchaseDetailService purchaseDetailService;
    @Autowired
    private WmsWareSkuService wareSkuService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<WmsPurchaseEntity> page = this.page(
                new Query<WmsPurchaseEntity>().getPage(params),
                new QueryWrapper<WmsPurchaseEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageUnreceivePurchases(Map<String, Object> params) {
        IPage<WmsPurchaseEntity> page = this.page(
                new Query<WmsPurchaseEntity>().getPage(params),
                new LambdaQueryWrapper<WmsPurchaseEntity>()
                        .eq(WmsPurchaseEntity::getStatus, WareConstant.PurchaseStatusEnum.CREATED.getCode())
                        .or().eq(WmsPurchaseEntity::getStatus, WareConstant.PurchaseStatusEnum.ASSIGNED.getCode())
        );

        return new PageUtils(page);
    }

    /**
     * 合并采购需求
     *
     * @param mergePurchaseDetailVO
     */
    @Transactional
    @Override
    public void mergePurchaseDetail(MergePurchaseDetailVO mergePurchaseDetailVO) {
        List<Long> purchaseDetailIds = mergePurchaseDetailVO.getItems();
        if (purchaseDetailIds == null || purchaseDetailIds.isEmpty()) {
            return;
        }
        // 正在采购的采购需求不能合并
        LambdaQueryWrapper<WmsPurchaseDetailEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.select(WmsPurchaseDetailEntity::getId)
                .in(WmsPurchaseDetailEntity::getId, purchaseDetailIds)
                .and(wrapper -> {
                    wrapper.eq(WmsPurchaseDetailEntity::getStatus, WareConstant.PurchaseDetailStatusEnum.CREATED.getCode())
                            .or().eq(WmsPurchaseDetailEntity::getStatus, WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode());
                });

        List<Long> needPurchaseIds = purchaseDetailService.listObjs(queryWrapper);

        if (needPurchaseIds == null ||needPurchaseIds.size() == 0) {
            return;
        }

        Long purchaseId = mergePurchaseDetailVO.getPurchaseId();
        // 没有采购单id，则先新建采购单再合并采购需求
        if (purchaseId == null) {
            // 新建采购单
            WmsPurchaseEntity purchase = new WmsPurchaseEntity();
            purchase.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode());
            baseMapper.insert(purchase);

            purchaseId = purchase.getId();
        }

        // 合并采购需求
        final Long finalPurchaseId = purchaseId;
        List<WmsPurchaseDetailEntity> purchaseDetailEntities = needPurchaseIds.stream().map(item -> {
            WmsPurchaseDetailEntity purchaseDetail = new WmsPurchaseDetailEntity();
            purchaseDetail.setId(item);
            purchaseDetail.setPurchaseId(finalPurchaseId);
            purchaseDetail.setStatus(WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode());
            return purchaseDetail;
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(purchaseDetailEntities);
    }

    /**
     * 领取采购单
     * @param purchaseIds
     */
    @Transactional
    @Override
    public void receive(List<Long> purchaseIds) {
        if (purchaseIds == null || purchaseIds.size() == 0){
            return;
        }

        // 查询当前采购单状态是新建或已分配的采购单集合
        LambdaQueryWrapper<WmsPurchaseEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(WmsPurchaseEntity::getId, purchaseIds)
                .and(wrapper -> {
                    wrapper.eq(WmsPurchaseEntity::getStatus, WareConstant.PurchaseStatusEnum.CREATED.getCode())
                            .or().eq(WmsPurchaseEntity::getStatus, WareConstant.PurchaseStatusEnum.ASSIGNED.getCode());
                });

        List<WmsPurchaseEntity> purchaseEntities = this.list(queryWrapper);

        if (purchaseEntities == null || purchaseEntities.size() == 0){
            return;
        }

        // 修改采购项的状态
        List<WmsPurchaseEntity> updatePurchases = purchaseEntities.stream().map(purchase -> {
            WmsPurchaseEntity purchaseEntity = new WmsPurchaseEntity();
            purchaseEntity.setId(purchase.getId());
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.RECEIVE.getCode());

            List<WmsPurchaseDetailEntity> purchaseDetailEntities = purchaseDetailService.listByPurchaseId(purchase.getId());

            List<WmsPurchaseDetailEntity> updatePurchaseDetails = purchaseDetailEntities.stream().map(purchaseDetail -> {
                WmsPurchaseDetailEntity purchaseDetailEntity = new WmsPurchaseDetailEntity();
                purchaseDetailEntity.setId(purchaseDetail.getId());
                purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.BUYING.getCode());
                return purchaseDetailEntity;
            }).collect(Collectors.toList());

            purchaseDetailService.updateBatchById(updatePurchaseDetails);
            return purchaseEntity;
        }).collect(Collectors.toList());

        // 修改采购单状态
        this.updateBatchById(updatePurchases);
    }

    /**
     * 完成采购单
     * @param purchaseDoneVO
     */
//    @Transactional(rollbackFor = Exception.class) // 远程调用出异常后，不想让事务回滚的第二种方式
    @Transactional
    @Override
    public void done(PurchaseDoneVO purchaseDoneVO) {
        List<PurchaseItemDoneVO> items = purchaseDoneVO.getItems();
        if (items == null || items.size() == 0){
            return;
        }

        boolean isPurchaseDone = true;
        List<WmsPurchaseDetailEntity> updatePurchaseDetailEntities = new ArrayList<>();
        // 对每一个采购项进行入库操作
        for (PurchaseItemDoneVO item : items) {
            WmsPurchaseDetailEntity detailEntity = new WmsPurchaseDetailEntity();
            detailEntity.setId(item.getItemId());
            if (WareConstant.PurchaseDetailStatusEnum.FAILURE.getCode() == item.getStatus().intValue()){
                isPurchaseDone = false;
            }else{
                // 完成入库操作
                WmsPurchaseDetailEntity detail = purchaseDetailService.getById(item.getItemId());
                wareSkuService.addStock(detail.getSkuId(), detail.getWareId(), detail.getSkuNum());
            }
            // 可以使用前端传来的status
            detailEntity.setStatus(item.getStatus());
            updatePurchaseDetailEntities.add(detailEntity);
        }
        // 批量更新采购项状态
        purchaseDetailService.updateBatchById(updatePurchaseDetailEntities);

        // 更新采购单状态
        WmsPurchaseEntity purchaseEntity = new WmsPurchaseEntity();
        purchaseEntity.setId(purchaseDoneVO.getId());
        purchaseEntity.setStatus(isPurchaseDone ? WareConstant.PurchaseStatusEnum.FINISH.getCode() : WareConstant.PurchaseStatusEnum.ERROR.getCode());
        this.updateById(purchaseEntity);
    }

}
